/**
 * 蛇的类
 */
class Snake {
    // 表示蛇的元素
    protected readonly head:HTMLElement;

    private bodies:HTMLElement[];
    private element: HTMLElement;

    constructor() {
        this.element = document.getElementById("snake")
        this.head = document.querySelector("#snake > div");
        this.bodies = this.element.getElementsByTagName('div') as unknown as HTMLElement[]
    }

    get X(){
        return this.head.offsetLeft;
    }

    get Y(){
        return this.head.offsetTop;
    }

    /**
     * 设置蛇的X坐标
     *
     * @param   {[Number]}  value  蛇的X坐标
     */
    set X(value){
        if(value < 0){
            value = 290
        }
        if(value > 290){
            value = 0
        }
        
        // 当蛇在向左移动时不让它向右移动 当蛇向右移动时不让它向左移动
        if(this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value){
            if(value > this.X){
                value = this.X - 10
            }else{
                value = this.X + 10
            }
        }

        this.moveBody()
        this.head.style.left =  `${value}px`
    }

    /**
     * 设置蛇的Y坐标
     *
     * @param   {[Number]}  value  蛇的Y坐标
     */
    set Y(value){
        if(value < 0){
            value = 290
        }
        if(value > 290){
            value = 0
        }

        // 当蛇在向上移动时不让它向下移动 当蛇向下移动时不让它向上移动
        if(this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value){
            if(value > this.Y){
                value = this.Y - 10
            }else{
                value = this.Y + 10
            }
        }

        this.moveBody()
        this.head.style.top =  `${value}px`
    }

    /**
     * 蛇增加身体
     */
    addBody(){
        // 向element添加div
        this.element.insertAdjacentHTML("beforeend", "<div></div>");
    }

    /**
     * 检测蛇是否触碰到自己的身体
     */
    touchBody(){
        for (let i = 1; i < this.bodies.length; i++) {
            if(this.bodies[i].offsetLeft === this.X && this.bodies[i].offsetTop === this.Y){
                return true
            }
        }
        return false
    }

    /**
     * 移动蛇的身体
     */
    moveBody(){
        // 对于蛇的移动
        // 1：每次把蛇当前身体的坐标改变为当前身体上一个的坐标即可实现身体的移动。
        // 2：从后往前遍历 改变身体的坐标。
        // 3：最后去移动头部的坐标，即可完成整个蛇的移动。
        for (let i = this.bodies.length - 1 ; i > 0 ; i--) {
            let X = this.bodies[i-1].offsetLeft
            let Y = this.bodies[i-1].offsetTop
            this.bodies[i].style.left = X + 'px'
            this.bodies[i].style.top = Y + 'px'
        }
    }
}

export default Snake


